﻿using NLog;
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;
using Telerik.WinControls.UI.Docking;
using System.Collections.Generic;
using FreesenseSubAIS.UI;
using FreesenseSubAIS.Core;
using FreesenseSubAIS.ImageProcess;
using FreesenseSubAIS.InspProcess;
using System.Linq;

namespace FreesenseSubAIS
{
    public partial class FormMainNew : RadForm
    {
        private AutoResetEvent _retset;
        private AutoResetEvent _resetEvent;//单次批量检测完成
        private readonly ILogger _log;
        private List<ImageGroup> _listImageGr;
        private string _selectName;
        private int _itemindex;
        private bool _allowClosing;
        private string _selpath;

        public FormMainNew()
        {
            InitializeComponent();
            splitPanel3.Collapsed = true;
            listView1.MultiSelect = false;
            listView1.LargeImageList = new ImageList();
            listView1.LargeImageList.ImageSize = new Size(100, 100);
            _log = LogManager.GetCurrentClassLogger();
            _retset = new AutoResetEvent(true);
            _resetEvent = new AutoResetEvent(false);
            _listImageGr = new List<ImageGroup>();
            versionLabel.Text = ProductVersion.ToString();
        }

        private void ParamSettingBtn_Click(object sender, EventArgs e)
        {
            try
            {
                Device.EnginerModel = false;
                LogInForm lf = new LogInForm();
                lf.ShowDialog();
                if (!Device.EnginerModel)
                    return;
                configForm cf = new configForm();
                cf.ShowDialog();
                cf.Dispose();
                Device.EnginerModel = false;
                productIdLabel.Text = string.Format("当前型号:{0}", Device.Parameter.DefaultProductId);
                InspEntity.Intance.GetProjectConfig();
                LoadDorkControl();
            }
            catch { }
        }

        private void menuUser_Click(object sender, EventArgs e)
        {
            UserForm user = new UserForm();
            if (user.ShowDialog() == DialogResult.OK)
            {
                operatorIDLabel.Text = string.Format("操作员ID:{0}", Device.Parameter.CurentOperator);
            }
        }

        private void FormMainNew_Load(object sender, EventArgs e)
        {
            LoadDorkControl();
            InspEntity.Intance.MsgEvent += Intance_MsgEvent;
            InspEntity.Intance.ChangValue += Intance_ChangValue;
            operatorIDLabel.Text = Device.Parameter.CurentOperator;
        }

        private void Intance_ChangValue(int value)
        {
            if (value > progressBar1.Maximum)
                return;
            InvokeIfNeeded(progressBar1, () => progressBar1.Value1 = value);
        }

        private void Intance_MsgEvent(string arg1, int arg2)
        {
            switch (arg2)
            {
                case 0://开始
                    Start(arg1);
                    break;
                case 1://切换产品
                    ChangeProductEvent(arg1);
                    break;
                case 2://显示总结果
                    DisResult(arg1);
                    break;
                case 3://返回进度
                    ReportProcess(string.Format("{0}-{1}", DateTime.Now.ToString("HH:mm:ss"), arg1));
                    break;
            }
        }

        private void ReportProcess(string arg1)
        {
            InvokeIfNeeded(ProcessLv, new Action(() => ProcessLv.Items.Add(arg1)));
        }

        private void DisResult(string res)
        {
            _log.Debug("MainForm更新结果：" + res.ToString());
            Action changesys = () =>
            {
                if (res.Equals("True"))
                {
                    ChangeBackColor(totalresultLabel, Color.Green);
                    totalresultLabel.Text += "OK";
                }
                else
                {
                    ChangeBackColor(totalresultLabel, Color.Red);
                    totalresultLabel.Text += "NG";
                }
                if (listView1.Items.Count > 0)
                {
                    listView1.Items[0].Selected = true;
                }
                else
                {
                    imageRenderBox1.ClearRectBox();
                    imageRenderBox1.ClearImage();
                    imageRenderBox1.DisplayRefresh();
                }
                progressBar1.Value1 = progressBar1.Maximum;
            };
            InvokeIfNeeded(radStatusStrip1, changesys);
        }

        private void ChangeProductEvent(string arg1)
        {
            productIdLabel.Text = string.Format("当前型号：{0}", arg1);
        }

        internal void Start(string id)
        {
            try
            {
                #region 控件清空
                Action actionRestart = () =>
                {
                    radTextBox1.Text = id;
                    ChangeBackColor(progressBar1, Color.CornflowerBlue);
                    progressBar1.Value1 = 0;
                    progressBar1.Value2 = 0;
                    progressBar1.Maximum = InspEntity.Intance.InspLogic.GetNeeds();
                    progressBar1.Refresh();
                    totalresultLabel.Text = "检测结果:";
                    ChangeBackColor(totalresultLabel, Color.CornflowerBlue);
                    imageRenderBox1.ClearRectBox();
                    imageRenderBox1.ClearImage();
                    imageRenderBox1.DisplayRefresh();
                    for (var i = 0; i < listView1.LargeImageList.Images.Count; i++)
                    {
                        var img = listView1.LargeImageList.Images[i];
                        img.Dispose();
                        img = null;
                    }
                    listView1.LargeImageList.Images.Clear();
                    listView1.Items.Clear();
                    listBox1.Items.Clear();
                    foreach (var s in _listImageGr)
                    {
                        s.Clear(true);
                    }
                    ProcessLv.Items.Clear();
                    InspItemLV.Items.Clear();
                };
                InvokeIfNeeded(this, actionRestart);
                #endregion 控件清空
                _log.Debug("\r\nMainForm=>" + "检测开始");
            }
            catch (Exception ex)
            {
                _log.Error("FormMain.Start()异常：" + ex.Message);
            }
        }

        private void InvokeIfNeeded<T>(T ctl, Action doit) where T : Control
        {
            if (ctl.InvokeRequired)
            {
                ctl.BeginInvoke(doit);
            }
            else
            {
                doit();
            }
        }

        private void ChangeBackColor<T>(T ctrl, Color color) where T : RadControl
        {
            try
            {
                ((Telerik.WinControls.Primitives.FillPrimitive)(ctrl.GetChildAt(0).GetChildAt(0))).BackColor = color;
                ((Telerik.WinControls.Primitives.FillPrimitive)(ctrl.GetChildAt(0).GetChildAt(0))).BackColor2 = color;
                ((Telerik.WinControls.Primitives.FillPrimitive)(ctrl.GetChildAt(0).GetChildAt(0))).BackColor3 = color;
                ((Telerik.WinControls.Primitives.FillPrimitive)(ctrl.GetChildAt(0).GetChildAt(0))).BackColor4 = color;
            }
            catch (Exception ex) { }
        }
        private void LoadDorkControl()
        {
            try
            {
                _listImageGr.Clear();
                _allowClosing = true;
                radDock1.CloseAllWindows();
                _allowClosing = false;
                radRibbonBarButtonGroup10.Items.Clear();
                foreach (var c in Device.DeviceEntityControl.Cameras)
                {
                    if (c != null && !string.IsNullOrEmpty(c.CameraName))
                    {
                        var cs = new ImageGroup(c.CameraName);
                        cs.Name = c.CameraName;
                        radDock1.DockControl(cs, DockPosition.Top, DockType.ToolWindow);
                        cs.LoadData();
                        cs.IndexChanged += Cs_IndexChanged;
                        _listImageGr.Add(cs);
                        var cbe = new RadCheckBoxElement { Text = c.CameraName };
                        cbe.ToggleStateChanging += Cbe_ToggleStateChanging; ;
                        radRibbonBarButtonGroup10.Items.Add(cbe);
                    }
                }

                ImageManage.Instance.RefreshGroupItem += Instance_RefreshGroupItem;
                ImageManage.Instance.RefreshGroupResult += Instance_RefreshGroupResult;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Cbe_ToggleStateChanging(object sender, StateChangingEventArgs args)
        {
            var rcb = sender as RadCheckBoxElement;
            try
            {
                var index = _listImageGr.FindIndex(x => x.Name.Equals(rcb.Text));
                if (index < 0)
                    return;
                if (rcb.Checked)
                {
                    rcb.Checked = SetVirualCamera(rcb.Text);
                }
                else
                {
                    ImageManage.Instance.CancelVirtualCamera(rcb.Text);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                rcb.Checked = false;
            }
        }

        private void Cs_IndexChanged(object sender, int e)
        {
            _itemindex = e;
            ShowCurrentInspItem(ImageManage.Instance.QueryItem(sender as string, e));
        }

        private void Instance_RefreshGroupResult(object sender, GroupResult e)
        {
            var index = _listImageGr.FindIndex(x => x.Name.Equals(sender as string));
            if (index > -1)
            {
                _listImageGr[index].RefreshGroupResult(e);
            }
        }

        private void Instance_RefreshGroupItem(object sender, ResultDisplayRowResult e)
        {
            var index = _listImageGr.FindIndex(x => x.Name.Equals(sender as string));
            if (index > -1)
            {
                _listImageGr[index].RefreshListView(e);
            }
            if (_selectName.Equals(sender as string))
            {
                _itemindex = e.Index;
                ShowCurrentInspItem(e);
            }
        }

        private void HideRightPanel_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            splitPanel3.Collapsed = HideRightPanel.IsChecked;
        }

        private void radRadioRow_Button_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            if (radRadioRow_Button.IsChecked)
            {

            }
        }

        #region 显示检测项细节
        private void ShowCurrentInspItem(ResultDisplayRowResult item)
        {
            try
            {
                if (item == null)
                    return;
                ShowSummary(item);
                ShowImag(item, showErrRegionCB.Checked, showTestDataRCB.Checked);
                InvokeIfNeeded(listView1, new Action(() => CutErrRegion(item, listView1)));
            }
            catch (Exception ex)
            {

            }
        }
        /// <summary>
        /// 显示统计信息
        /// </summary>
        /// <param name="item"></param>
        private void ShowSummary(ResultDisplayRowResult item)
        {
            try
            {
                InvokeIfNeeded(InspItemLV, new Action(() =>
               {
                   InspItemLV.Items.Clear();
                   InspItemLV.Items.Add(item.SourceName);//相机名
                   InspItemLV.Items.Add(item.ItemName);//检测项名
                   InspItemLV.Items.Add(string.Format("缺陷总量：{0}", item.ErrCol.Count));//缺陷总量
                   var itype = "缺陷类型枚举：";
                   if (item.ErrDiff.Count > 0)
                   {
                       var dist = item.ErrDiff.Distinct().ToList();
                       dist.ForEach(x => itype += (x + "、"));
                   }
                   else
                       itype += "Null";
                   InspItemLV.Items.Add(itype.TrimEnd('、'));//检测项名
               }));
            }
            catch (Exception ex)
            { }
        }
        /// <summary>
        /// show image to ImageRender
        /// </summary>
        /// <param name="item"></param>
        /// <param name="showERegion"></param>
        /// <param name="ShowData"></param>
        private void ShowImag(ResultDisplayRowResult item, bool showERegion, bool ShowData)
        {
            if (item == null)
                return;
            Bitmap bbm = null;
            try
            {
                bbm = (Bitmap)item.InspedImg.Clone();
                int w = bbm.Width, h = bbm.Height;
                if (showERegion && !ShowData)
                {
                    var tempCol = item.ErrCol;
                    var tempRow = item.ErrRow;
                    imageRenderBox1.ClearRectBox();
                    imageRenderBox1.ClearString();
                    for (int i = 0; i < tempCol.Count; i++)
                        imageRenderBox1.AddRectBox(80, 4, tempCol[i], tempRow[i]);
                    imageRenderBox1.DisplayImage(bbm);
                    imageRenderBox1.DisplayRefresh();
                }
                else if (showERegion && ShowData)
                {
                    var tempCol = item.ErrCol;
                    var tempRow = item.ErrRow;
                    var tempValue = item.ErrValue;
                    var tempType = item.ErrType;
                    var tempDiff = item.ErrDiff;
                    imageRenderBox1.ClearRectBox();
                    imageRenderBox1.ClearString();
                    if (tempDiff != null)
                        for (int i = 0; i < tempCol.Count; i++)
                        {
                            imageRenderBox1.AddRectBox(80, 4, tempCol[i], tempRow[i]);
                            imageRenderBox1.AddString(8, string.Format("{0},{1},{2}", tempType[i], tempValue[i], tempDiff[i]), tempCol[i], tempRow[i], 0, 0, 255);
                        }
                    else
                        for (int i = 0; i < tempCol.Count; i++)
                        {
                            imageRenderBox1.AddRectBox(80, 4, tempCol[i], tempRow[i]);
                            imageRenderBox1.AddString(8, string.Format("{0},{1}", tempType[i], tempValue[i]), tempCol[i], tempRow[i], 0, 0, 255);
                        }
                    imageRenderBox1.DisplayImage(bbm);
                    imageRenderBox1.DisplayRefresh();
                }
                else if (!showERegion && ShowData)
                {
                    var tempCol = item.ErrCol;
                    var tempRow = item.ErrRow;
                    var tempValue = item.ErrValue;
                    var tempType = item.ErrType;
                    var tempDiff = item.ErrDiff;
                    imageRenderBox1.ClearRectBox();
                    imageRenderBox1.ClearString();
                    if (tempDiff != null)
                        for (int i = 0; i < tempCol.Count; i++)
                        {
                            imageRenderBox1.AddRectBox(80, 4, tempCol[i], tempRow[i]);
                        }
                    else
                        for (int i = 0; i < tempCol.Count; i++)
                        {
                            imageRenderBox1.AddRectBox(80, 4, tempCol[i], tempRow[i]);
                        }
                    imageRenderBox1.DisplayImage(bbm);
                    imageRenderBox1.DisplayRefresh();
                }
                else
                {
                    imageRenderBox1.ClearRectBox();
                    imageRenderBox1.ClearString();
                    imageRenderBox1.DisplayImage(bbm);
                    imageRenderBox1.DisplayRefresh();
                }
                bbm.Dispose();
                bbm = null;
            }
            catch (Exception ex)
            {
                if (bbm != null)
                {
                    bbm.Dispose();
                }
            }
        }
        /// <summary>
        /// show detail to ListView
        /// </summary>
        /// <param name="item"></param>
        /// <param name="lv"></param>
        private void CutErrRegion(ResultDisplayRowResult item, ListView lv)
        {
            lv.Items.Clear();
            List<int> C = item.ErrCol;
            List<int> R = item.ErrRow;
            Bitmap bitmap = new Bitmap(85, 85);
            Graphics g = Graphics.FromImage(bitmap);
            if (C != null && C.Count != 0)
            {
                int jcount = 0;
                Bitmap bbm = (Bitmap)item.InspedImg.Clone();
                int sxCount = C.Count - jcount;
                if (sxCount <= 4)
                {
                    for (int i = 0; i < sxCount; i++)
                    {
                        int colc = (int)C[i + jcount];
                        int rowc = (int)R[i + jcount];

                        if (sxCount == 1)//1个的方案
                        {
                            g.DrawImage(bbm, new Rectangle(17, 17, 50, 50), (int)colc - 20, (int)rowc - 20, 40, 40, GraphicsUnit.Pixel);
                        }
                        else if (sxCount == 2)//2个的方案
                        {
                            g.DrawImage(bbm, new Rectangle(i % 2 == 0 ? 0 : 45, 20, 40, 40), (int)colc - 20, (int)rowc - 20, 40, 40, GraphicsUnit.Pixel);
                        }
                        else //3和4
                        {
                            g.DrawImage(bbm, new Rectangle(i % 2 == 0 ? 0 : 45, (i / 2) * 45, 40, 40), (int)colc - 20, (int)rowc - 20, 40, 40, GraphicsUnit.Pixel);
                        }
                    }
                }
                else//大于4
                {
                    for (int i = 0; i < 4; i++)
                    {
                        int colc = (int)C[i + jcount];
                        int rowc = (int)R[i + jcount];

                        g.DrawImage(bbm, new Rectangle(i % 2 == 0 ? 0 : 45, (i / 2) * 45, 40, 40), (int)colc - 20, (int)rowc - 20, 40, 40, GraphicsUnit.Pixel);
                    }
                }
                Action actionNGAdd = () =>
                {
                    lv.LargeImageList.Images.Add(bitmap);
                    if (C.Count > 4)//jcount == 4 && 
                    {
                        lv.Items.Add(item.Index.ToString(), string.Format("{0}-{1}", item.ItemName, item.Msg), lv.LargeImageList.Images.Count - 1);
                        lv.Items[lv.Items.Count - 1].ForeColor = Color.Gold;// Color.SpringGreen
                    }
                    else
                    {
                        lv.Items.Add(item.Index.ToString(), string.Format("{0}-{1}", item.ItemName, item.Msg), lv.LargeImageList.Images.Count - 1);
                        if (!item.Result)
                        {
                            lv.Items[lv.Items.Count - 1].ForeColor = Color.Red;// Color.SpringGreen
                        }
                        else
                            lv.Items[lv.Items.Count - 1].ForeColor = Color.Green;// Color.SpringGreen
                    }
                };
                InvokeIfNeeded(lv, actionNGAdd);
                g.Dispose();
                bbm.Dispose();
                bbm = null;
            }
            else
            {
                if (item.Result)
                {
                    Action actionOKAdd = () =>
                    {
                        lv.LargeImageList.Images.Add(bitmap);
                        lv.Items.Add(item.Index.ToString(), string.Format("{0}-{1}", item.ItemName, item.Msg), lv.LargeImageList.Images.Count - 1);
                        lv.Items[lv.Items.Count - 1].ForeColor = Color.Green;// Color.SpringGreen
                    };
                    InvokeIfNeeded(lv, actionOKAdd);
                }
                else
                {
                    Action actionNNGAdd = () =>
                    {
                        lv.LargeImageList.Images.Add(bitmap);
                        lv.Items.Add(item.Index.ToString(), string.Format("{0}-{1}", item.ItemName, item.Msg), lv.LargeImageList.Images.Count - 1);
                        lv.Items[lv.Items.Count - 1].ForeColor = Color.Red;// Color.SpringGreen

                    };
                    InvokeIfNeeded(lv, actionNNGAdd);
                }
                g.Dispose();
            }
        }
        #endregion

        private void radDock1_ActiveWindowChanged(object sender, DockWindowEventArgs e)
        {
            _selectName = e.DockWindow.Text;
        }

        private void RefreshDetialBtn_Click(object sender, EventArgs e)
        {
            try
            {
                ClearControlGroup();
                ImageManage.Instance.RefreshInspItem();
            }
            catch (Exception ex)
            {
                radTextBox1.Text = "HDSKJHFK";
            }
        }
        private void ClearControlGroup()
        {
            foreach (var s in _listImageGr)
                s.Clear(true);
        }

        private void radDock1_DockWindowClosing(object sender, DockWindowCancelEventArgs e)
        {
            if (!_allowClosing)
            {
                e.Cancel = true;
            }
        }

        private void ClearCacheBtn_Click(object sender, EventArgs e)
        {
            Start("");
        }

        private void radCheckBoxElement1_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            radRibbonBarButtonGroup2.Visibility = radCheckBoxElement1.Checked ? ElementVisibility.Visible : ElementVisibility.Collapsed;
        }

        private void ShotImageBtn_Click(object sender, EventArgs e)
        {
            CheckedItemsCombox.Items.Clear();
            foreach (var s in Device.defaultProduct.ParamList)
            {
                CheckedItemsCombox.Items.Add(s.PicParameter.Picname);
            }
        }

        private void showErrRegionCB_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            ShowImag(ImageManage.Instance.QueryItem(_selectName, _itemindex), showErrRegionCB.Checked, showTestDataRCB.Checked);
        }

        private void IsDisImage_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            Device.DisDetail = IsDisImage.Checked;
        }

        private void SourceImageSaveCbox_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {

        }

        private void ManualInsp_Btn_Click(object sender, EventArgs e)
        {

        }

        private void SingleGroupBtn_Click(object sender, EventArgs e)
        {
            try
            {
                SetVirualCamera(_selectName);
                InspEntity.Intance.ExcuteCmd();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:" + ex.Message);
            }
        }
        private bool SetVirualCamera(string cname)
        {
            var dialog = new FolderBrowserDialog();
            //dialog.RootFolder = Environment.SpecialFolder.MyComputer;
            if (_selpath == null)
            {
                dialog.SelectedPath = "E:\\Huifu\\CodeProjects\\AIS\\SubAIS0096\\165043";
            }
            else
            {
                dialog.SelectedPath = _selpath;
            }
            dialog.Description = string.Format("请选择 {0} 的图片文件夹", cname);
            if (dialog.ShowDialog() != DialogResult.OK) return false;
            _selpath = dialog.SelectedPath;
            ImageManage.Instance.ChangeVirtualCamera(cname, _selpath);
            return true;
        }

        private void MultiGroupBtn_Click(object sender, EventArgs e)
        {
            try
            {
                var times = 0;
                if (!int.TryParse(timesTBox.Text, out times))
                    return;
                if (!repeatBox.Checked)
                    times = 0;
                var count = times + 1;

                InspEntity.Intance.ExcuteCmd();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error:" + ex.Message);
            }
        }

        private void radCheckBoxElement3_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            radRibbonBarButtonGroup11.Visibility = radCheckBoxElement3.Checked ? ElementVisibility.Visible : ElementVisibility.Collapsed;
        }
    }
}
